package Lab4JavaConcurrency;
import java.util.concurrent.CountDownLatch;

public class Main implements Runnable{
	private double[][] matrixA;
	private double[][] matrixB;
	private double[][] result;
	private int index;
	private int gap;
	private CountDownLatch count;
	
	public Main(int index, int gap, double[][] matrixA, double[][] matrixB, double[][] result, CountDownLatch count) {
		this.index = index;
		this.gap = gap;
		this.matrixA = matrixA;
		this.matrixB = matrixB;
		this.result = result;
		this.count = count;
	}
	@Override
	public void run() {	
		for (int i = index * gap; i < (index + 1) * gap; i++) {
			for (int j = 0; j <  matrixB[0].length; j++) {
				for (int k = 0; k <  matrixB.length; k++)
					result[i][j] = matrixA[i][k] *  matrixB[k][j];
			}
		}
		// 线程数减1
		count.countDown();	
	}
	
	public static void main(String[] args) {
		long startTime;
		long endTime;
		int a = 10;
		int b = 10;
		int c = 10;
		// int a = (int)(Math.random()*10);
		// int b = (int)(Math.random()*10);
		// int c = (int)(Math.random()*10);
		System.out.println("a = "+a + "  b = " + b + "  c = " + c);
		MatrixGenerator matrix1 = new MatrixGenerator(a,b);
		MatrixGenerator matrix2 = new MatrixGenerator(b,c);
		System.out.println("随机矩阵1：");
		double[][] matrixA = matrix1.getMatrix(a,b);
		System.out.println("随机矩阵2：");
    	double[][] matrixB = matrix2.getMatrix(b,c);		
    	// 串行计算结果
    	double[][] serial = new double[a][c];
    	// 并行计算结果
		double[][] parallel = new double[a][c];
		
		//串行计算
	    startTime = System.currentTimeMillis();
		for(int i = 0 ; i < matrixA.length ;i++) {
			for(int j = 0 ; j < matrixB[0].length ; j++) {
				for(int k = 0 ; k < matrixA[0].length ; k++) {
					serial[i][j] =  matrixA[i][k] * matrixB[k][j];
				}
			}
		}
		endTime = System.currentTimeMillis();
		System.out.println("计算结果: ");
		for(int i = 0 ; i < serial.length ;i++) {
			for(int j = 0 ; j <serial[i].length ; j++) {
				System.out.print(serial[i][j] + "  ");
			}
			System.out.println();
		}
		System.out.println("----------------------------------------------------------------");
		System.out.println("串行运算");
		System.out.println("开始时间: " + startTime +" 结束时间: " + endTime);
		System.out.println("运行时间: " + (endTime - startTime));
		
		//并行计算
		int threadNum = 5;//子线程数量
		int gap = matrixA.length / threadNum;//子线程的分片计算间隔
		
		CountDownLatch count = new CountDownLatch(threadNum);
		startTime = System.currentTimeMillis();

		for (int i = 0; i < threadNum; i++) {
			Main multiple = new Main(i, gap, matrixA, matrixB, parallel, count);
			Thread th = new Thread(multiple);
			th.start();
		}
		
		try {
			count.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		endTime = System.currentTimeMillis();
		System.out.println("----------------------------------------------------------------");
		System.out.println("并行运算");
		System.out.println("开始时间: " + startTime +" 结束时间: " + endTime);
		System.out.println("运行时间: " + (endTime - startTime));
	}
}